package yawning.mew.cat;

import java.util.Map;

import yawning.mew.cat.CatModelSimState.CatTargetData;
import yawning.mew.cat.EventMeleeSwing.MeleeStats;
import yawning.mew.cat.SwipeAction.SwipeStats;
import yawning.mew.sim.SimulationEvent;
import yawning.mew.sim.SimulationTarget;

public class EventLogDamage extends SimulationEvent {
	private CatModelSimState mState;
	private int mNrEntries;
	private long mPrevTotalDamage;
	private double mLastTime;
	double[] mDamageDone;

	EventLogDamage(CatModelSimState state) {
		super(state.mSimEngine);
		mState = state;

		mDamageDone = new double[(int) Math.ceil(mState.mSimEngine.getEndTime()) + 2];

		// We want to call this at t=0.0 but since we don't have all the events wired up, fill the result in.
		mDamageDone[0] = 0;
		mNrEntries = 1;

		// With a 1.0 sec GCD, events potentially can end up being GCD aligned.  Offset logging ever so slightly.
		schedule(Double.MIN_VALUE);
	}

	@Override
	public void onTick() {
		double simTime = mState.mSimEngine.getSimTime();
		if (mLastTime == simTime) return;
		mLastTime = simTime;

		long totalDamage = 0;

		for (Map.Entry<String,SimulationTarget> entry : mState.mTargetMap.entrySet()) {
			SimulationTarget target = entry.getValue();
			CatTargetData td = (CatTargetData) target.getTargetData();

			SwipeStats swipeStats = mState.mSwipeAction.mDamageStats.get(target);
			if (swipeStats != null) {
				totalDamage += swipeStats.mSwipeDamage;
			}

			MeleeStats meleeStats = mState.mMeleeSwingEv.mDamageStats.get(target);
			if (meleeStats != null) {
				totalDamage += meleeStats.mWhiteDamage;
				totalDamage += meleeStats.mFurySwipesDamage;
			}

			totalDamage += td.mClawAction.mClawDamage + td.mMangleAction.mMangleDamage + td.mRakeAction.mRakeDamage + td.mRakeAction.mRakeDotDamage + td.mShredAction.mShredDamage + td.mRipAction.mRipDamage + td.mFerociousBiteAction.mBiteDamage + td.mMaimAction.mMaimDamage + td.mRavageAction.mRavageDamage + td.mPounceAction.mPounceDamage + td.mTier_12_2pcEv.mFieryClawsDmg + td.mProcPhysDamage + td.mProcSpellDamage;
		}

		mDamageDone[mNrEntries] = totalDamage - mPrevTotalDamage;	// Log damage done over the sampling interval.
		mPrevTotalDamage = totalDamage;
		mNrEntries++;
	}

	@Override
	public void onExpire() {
		if (mState.mSimEngine.getSimTime() != mState.mSimEngine.getEndTime()) {
			schedule(mState.mSimEngine.getEndTime(), 1.0);	// Log at 1 Hz
		} else {
			onTick();
		}
	}
}